﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Inovance.InoMotionCotrollerShop.InoServiceContract.EtherCATConfigApi;
using System.Threading;

namespace example
{
    public partial class Form1 : Form
    {
        public List<int> mCaptPosList;
        public static UInt64 cardHandle;//轴卡操作句柄
        UInt32 retRtn; //函数接口返回值
        Int16 axNo = 0;//起始轴号
        Int16 count = 1;//轴数
        Int16 stopType = 1;//停止类型 0： 平滑停止 1： 急速停止
        public Form1()
        {
            InitializeComponent();
        }

        #region 初始化
        //打印日志
        private void ShowMessage(string msg)
        {
            listBox_RunSts.Items.Add(DateTime.Now.ToString() + " " + msg);
            listBox_RunSts.SelectedIndex = listBox_RunSts.Items.Count - 1;
            listBox_RunSts.SelectedIndex = -1;
        }        
        //卡初始化
        private void button_CardInit_Click(object sender, EventArgs e)
        {
            UInt32 masterStatus = 0;
            int cardNo = 0; //打开0号卡
            Int32 cardsNum = 0;
            try
            {
                //非必须步骤，读取电脑中轴卡的数量
                retRtn = ImcApi.IMC_GetCardsNum(ref cardsNum);
                if (retRtn != ImcApi.EXE_SUCCESS)
                {
                    ShowMessage("IMC_GetCardsNum failed 故障代码为：0x" + retRtn.ToString("x8"));
                }
                textBox_CardNum.Text = cardsNum.ToString();
                //【1】获取轴卡操作句柄
                retRtn = ImcApi.IMC_OpenCardHandle(cardNo, ref cardHandle);
                if (retRtn != ImcApi.EXE_SUCCESS)
                {
                    ShowMessage("IMC_OpenCardHandle failed 故障代码为：0x" + retRtn.ToString("x8"));
                }
                //【2】获取主站状态
                retRtn = ImcApi.IMC_GetECATMasterSts(cardHandle, ref masterStatus);
                if (retRtn != ImcApi.EXE_SUCCESS)
                {
                    ShowMessage("IMC_GetECATMasterSts failed 故障代码为：0x" + retRtn.ToString("x8"));
                }
                else
                {
                    if (masterStatus != ImcApi.EC_MASTER_OP)
                    {
                        //【3】下载设备参数
                        //deviceconfig.xml文件是由控制卡后台软件配置生成然后手动放到编译路径下，路径可自由选择；
                        retRtn = ImcApi.IMC_DownLoadDeviceConfig(cardHandle, ".\\deviceconfig.xml");
                        if (retRtn != ImcApi.EXE_SUCCESS)
                        {
                            ShowMessage("IMC_DownLoadDeviceConfig failed 故障代码为：0x" + retRtn.ToString("x8"));
                        }
                        //【4】启动总线
                        retRtn = ImcApi.IMC_ScanCardECAT(cardHandle, 1);            //0表示非阻塞式开卡，1表示阻塞式开卡；
                        if (retRtn != ImcApi.EXE_SUCCESS)
                        {
                            ShowMessage("IMC_ScanCardECAT failed 故障代码为：0x" + retRtn.ToString("x8"));
                        }
                        //【5】下载系统参数
                        //systemconfig.xml文件是由控制卡后台软件配置生成然后手动放到编译路径下，路径可自由选择；
                        retRtn = ImcApi.IMC_DownLoadSystemConfig(cardHandle, ".\\systemconfig.xml");
                        if (retRtn != ImcApi.EXE_SUCCESS)
                        {
                            ShowMessage("IMC_DownLoadSystemConfig failed 故障代码为：0x" + retRtn.ToString("x8"));
                        }
                    }
                }
                timer_UI.Enabled = true;
                textBox_CardNum.Text = cardsNum.ToString();
            }
            catch (Exception ex)
            {
                ShowMessage(ex.ToString());
            }
        }
        //关闭卡
        private void button_CloseCard_Click(object sender, EventArgs e)
        {
            try
            {
                timer_UI.Enabled = false;
                retRtn = ImcApi.IMC_CloseCard(cardHandle);
                if (retRtn != ImcApi.EXE_SUCCESS)
                {
                    ShowMessage(System.Reflection.MethodBase.GetCurrentMethod().Name + " failed 故障代码为：0x" + retRtn.ToString("x8"));
                    return;
                }
            }
            catch (Exception ex)
            {
                ShowMessage(ex.ToString());
            }
        }
        #endregion

        #region 控制
        //使能
        private void button_AxServoOn_Click(object sender, EventArgs e)
        {
            try
            {
                retRtn = ImcApi.IMC_AxServoOn(cardHandle, axNo, count);
                if (retRtn != ImcApi.EXE_SUCCESS)
                {
                    ShowMessage(System.Reflection.MethodBase.GetCurrentMethod().Name + " failed 故障代码为：0x" + retRtn.ToString("x8"));
                    return;
                }
                else
                {
                    ShowMessage("轴上使能成功");
                }
            }
            catch (Exception ex)
            {
                ShowMessage(ex.ToString());
            }
        }
        //下使能
        private void button_AxServoOff_Click(object sender, EventArgs e)
        {
            try
            {
                retRtn = ImcApi.IMC_AxServoOff(cardHandle, axNo, count);
                if (retRtn != ImcApi.EXE_SUCCESS)
                {
                    ShowMessage(System.Reflection.MethodBase.GetCurrentMethod().Name + " failed 故障代码为：0x" + retRtn.ToString("x8"));
                    return;
                }
                else
                {
                    ShowMessage("轴上失能成功");
                }
            }
            catch (Exception ex)
            {
                ShowMessage(ex.ToString());
            }
        }
        //停止
        private void button_AxMoveStop_Click(object sender, EventArgs e)
        {
            try
            {
                stopType = 1;//停止类型 0： 平滑停止 1： 急速停止
                retRtn = ImcApi.IMC_AxMoveStop(cardHandle, axNo, stopType);// 0平滑停止；1 急停停止
                if (retRtn != ImcApi.EXE_SUCCESS)
                {
                    ShowMessage(System.Reflection.MethodBase.GetCurrentMethod().Name + " failed 故障代码为：0x" + retRtn.ToString("x8"));
                    return;
                }
            }
            catch (Exception ex)
            {
                ShowMessage(ex.ToString());
            }
        }
        //清除轴状态
        private void button_ClrAxSts_Click(object sender, EventArgs e)
        {
            try
            {
                for (Int16 i = axNo; i < count; i++)
                {
                    retRtn = ImcApi.IMC_ClrAxSts(cardHandle, i);
                }
                if (retRtn != ImcApi.EXE_SUCCESS)
                {
                    ShowMessage(System.Reflection.MethodBase.GetCurrentMethod().Name + " failed 故障代码为：0x" + retRtn.ToString("x8"));
                    return;
                }
            }
            catch (Exception ex)
            {
                ShowMessage(ex.ToString());
            }
        }
        #endregion

        #region 轴状态与信息显示
        //将十进制整形转换为二进制显示的字符串
        private string ConvertDecimalToBinary(Int32 nAxSts) 
        {
            string strAxSts = "";
            Int32 nBitValue = 0x00;

            for (uint i = 0; i < 11; i++)
            {
                nBitValue = (Int32)(0x01 * Math.Pow(2.0, i));    //对nBitValue向左移1位，移到第几位通过i来控制
                if ((nAxSts & nBitValue) == nBitValue)
                {
                    strAxSts = "1" + strAxSts;
                }
                else
                {
                    strAxSts = "0" + strAxSts;
                }
            }
            return strAxSts;
        }
        //UI界面信息刷新
        private void timer_UI_Tick(object sender, EventArgs e)
        {
            try
            {
                timer_UI.Enabled = false;
                double[] PrfPosArray = { 0 };
                double[] EncPosArray = { 0 };
                double[] EncVelArray = { 0 };
                Int32[] AxStsArray = { 0 };
                Int32 CycleDis = 0;
                Int32 PrfPos = 0;
                Int32 EncPos = 0;
                //获取目标位置
                retRtn = ImcApi.IMC_GetAxPrfPos(cardHandle, axNo, PrfPosArray, count);
                if (retRtn != ImcApi.EXE_SUCCESS)
                {
                    ShowMessage("IMC_GetAxSts failed 故障代码为：0x" + retRtn.ToString("x8"));
                    return;
                }
                //获取反馈位置
                retRtn = ImcApi.IMC_GetAxEncPos(cardHandle, axNo, EncPosArray, count);
                if (retRtn != ImcApi.EXE_SUCCESS)
                {
                    ShowMessage("IMC_GetAxEncPos failed 故障代码为：0x" + retRtn.ToString("x8"));
                    return;
                }
                //获取反馈速度
                retRtn = ImcApi.IMC_GetAxEncVel(cardHandle, axNo, EncVelArray, count);
                if (retRtn != ImcApi.EXE_SUCCESS)
                {
                    ShowMessage("IMC_GetAxSts failed 故障代码为：0x" + retRtn.ToString("x8"));
                    return;
                }
                //获取伺服状态
                retRtn = ImcApi.IMC_GetAxSts(cardHandle, axNo, AxStsArray, count);
                if (retRtn != ImcApi.EXE_SUCCESS)
                {
                    ShowMessage("IMC_GetAxSts failed 故障代码为：0x" + retRtn.ToString("x8"));
                    return;
                }
                ////获取周期运动参数
                retRtn = ImcApi.IMC_GetCycleMovePara(cardHandle, axNo, ref CycleDis);//周期单圈长度值，范围[1 , 2^31 - 1]
                if (retRtn != ImcApi.EXE_SUCCESS)
                {
                    ShowMessage("IMC_GetCycleMovePara failed 故障代码为：0x" + retRtn.ToString("x8"));
                    return;
                }
                ////获取周期运动规划位置
                retRtn = ImcApi.IMC_GetCycleMovePrfPos(cardHandle, axNo, ref PrfPos);//规划位置值
                if (retRtn != ImcApi.EXE_SUCCESS)
                {
                    ShowMessage("IMC_GetCycleMovePrfPos failed 故障代码为：0x" + retRtn.ToString("x8"));//
                    return;
                }
                ////获取周期运动的编码器位置
                retRtn = ImcApi.IMC_GetCycleMoveEncPos(cardHandle, axNo, ref EncPos);//编码器位置值
                if (retRtn != ImcApi.EXE_SUCCESS)
                {
                    ShowMessage("IMC_GetCycleMoveEncPos failed 故障代码为：0x" + retRtn.ToString("x8"));
                    return;
                }

                textBox_AxPrfPos0.Text = PrfPosArray[0].ToString();
                textBox_AxEncPos0.Text = EncPosArray[0].ToString();
                textBox_AxEncVel0.Text = EncVelArray[0].ToString();
                //转化为二进制字符串显示
                textBox_AxSts0.Text = ConvertDecimalToBinary(AxStsArray[0]);              
                //到位信号判断
                textBox_AxStsArrive0.Text = (AxStsArray[0] & 0xC) == 0x8 ? "1" : "0";
                textBox_CycleMovePara.Text = CycleDis.ToString();
                textBox_CycleMovePrfPos.Text = PrfPos.ToString();
                textBox_CycleMoveEncPos.Text = EncPos.ToString();

                timer_UI.Enabled = true;
            }
            catch (Exception ex)
            {
                ShowMessage(ex.ToString());
            }            
        }
        #endregion    
     
        #region 功能测试
        //设置周期运动参数 功 能： 位置系统根据设定的一圈运动范围，进行周期运动循环计数的一种运动计数模式
        private void button_SetCycleMovePara_Click(object sender, EventArgs e)
        {
            try
            {
                Int32 cycleDis = 100000;//如果不关心单圈长度， 可以设置为2^31
                retRtn = ImcApi.IMC_SetCycleMovePara(cardHandle, axNo, cycleDis);
                if (retRtn != ImcApi.EXE_SUCCESS)
                {
                    ShowMessage(System.Reflection.MethodBase.GetCurrentMethod().Name + " failed 故障代码为：0x" + retRtn.ToString("x8"));
                }
                else
                {
                    ShowMessage(System.Reflection.MethodBase.GetCurrentMethod().Name + " 成功");
                }
            }
            catch (Exception ex)
            {
                ShowMessage(ex.ToString());
            }
        }
        //启动周期运动
        private void button_StartCycleMove_Click(object sender, EventArgs e)
        {
            try
            {
                Int32 tgtPos = 75000;
                Int16 posType = 1;//位置类型： 0 绝对， 1 相对
                double vel = 50000;//设置运行速度
                double acc = 10000000;//设置运行加速度
                double dec = 10000000;//设置运行减速度

                retRtn = ImcApi.IMC_SetSingleAxMvPara(cardHandle, axNo, vel, acc, dec);
                if (retRtn != ImcApi.EXE_SUCCESS)
                {
                    ShowMessage(System.Reflection.MethodBase.GetCurrentMethod().Name + "IMC_SetSingleAxMvPara failed 故障代码为：0x" + retRtn.ToString("x8"));
                }
                else
                {
                    ShowMessage(System.Reflection.MethodBase.GetCurrentMethod().Name + " 成功");
                }

                retRtn = ImcApi.IMC_StartCycleMove(cardHandle, axNo, tgtPos, posType);
                if (retRtn != ImcApi.EXE_SUCCESS)
                {
                    ShowMessage(System.Reflection.MethodBase.GetCurrentMethod().Name + "IMC_StartCycleMove failed 故障代码为：0x" + retRtn.ToString("x8"));
                }
                else
                {
                    ShowMessage(System.Reflection.MethodBase.GetCurrentMethod().Name + " 成功");
                }
            }
            catch (Exception ex)
            {
                ShowMessage(ex.ToString());
            }
        }
        //停止周期运动
        private void button_StopCycleMove_Click(object sender, EventArgs e)
        {
            try
            {
                stopType = 0;//停止类型 0： 平滑停止 1： 急速停止                
                retRtn = ImcApi.IMC_StopCycleMove(cardHandle, axNo, stopType);
                if (retRtn != ImcApi.EXE_SUCCESS)
                {
                    ShowMessage(System.Reflection.MethodBase.GetCurrentMethod().Name + " failed 故障代码为：0x" + retRtn.ToString("x8"));
                }
                else
                {
                    ShowMessage(System.Reflection.MethodBase.GetCurrentMethod().Name + " 成功");
                }
            }
            catch (Exception ex)
            {
                ShowMessage(ex.ToString());
            }
        }
        //设置周期运动的当前位置
        private void button_SetCycleMoveCurPos_Click(object sender, EventArgs e)
        {
            try
            {
                Int32 setPos = 0;
                retRtn = ImcApi.IMC_SetCycleMoveCurPos(cardHandle, axNo, setPos);
                if (retRtn != ImcApi.EXE_SUCCESS)
                {
                    ShowMessage(System.Reflection.MethodBase.GetCurrentMethod().Name + " failed 故障代码为：0x" + retRtn.ToString("x8"));
                }
                else
                {
                    ShowMessage(System.Reflection.MethodBase.GetCurrentMethod().Name + " 成功");
                }
            }
            catch (Exception ex)
            {
                ShowMessage(ex.ToString());
            }
        }
        #endregion
        

    }
}
